package simco.framework.gui.graph.base;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Stroke;

import javax.swing.JLabel;

import simco.framework.gui.graph.iface.Drawable;
import simco.framework.gui.graph.supp.BorderType;
import simco.framework.gui.graph.supp.LineEdge;
import simco.framework.gui.utils.Configuration;

/**
 * Tato trida reprezentuje graficky objekt obdelnikoveho
 * tvaru, tj. objek jenz je vykreslovan jako obdelnik s
 * vlastni velikosti, nazvem a typem oramovani.
 *
 * @author Matej Prokop, mythge@students.zcu.cz
 */
public abstract class GraphRectangle extends GraphObject
{
	/**
	 * Font pouzity pro vykreslovani textu normalnim (netucnim) pismem
	 */
	protected static final Font NORMAL_FONT = new Font(Configuration.FONT_NAME,
			Font.PLAIN, Configuration.getFontSize());
	
	/**
	 * Font pouzity pro vykreslovani textu tucnym pismem
	 */
	protected static final Font BOLD_FONT = new Font(Configuration.FONT_NAME,
			Font.BOLD, Configuration.getFontSize());
	
	/**
	 * Vychozi odsazeni od kraji pri vykreslovani objektu 
	 */
	protected static final int INSETS_SIZE = 10;
	
	/**
	 * Typ vykreslovaneho ohraniceni objektu
	 */
    private BorderType borderType;

    /**
     * Vizualizovany nazev objektu
     */
    protected String objectTitle;

    /**
     * Metrika pisma pouzivana pri vypoctu velikosti objektu, resp.
     * velikosti vykreslovaneho textu do objektu
     */
    protected FontMetrics fontMetrick;    

    /**
     * Vychozi nastavovany typ vykreslovaneho ohraniceni objektu
     */
    public static final BorderType DEFAULT_BORDER = BorderType.SOLID;

    /**
     * Vytvori novy graficky objekt ve tvaru obdelniku s
     * vlastnim zobrazovanym nazvem.  
     * 
     * @param objectId identifikator vytvoreneho objektu
     * @param tittle vizualizovany nazev objektu
     */
    public GraphRectangle(long objectId, String tittle)
    {
        super(objectId);
        borderType = DEFAULT_BORDER;
        objectTitle = tittle;
        
    	JLabel label = new JLabel();
    	fontMetrick = label.getFontMetrics(BOLD_FONT);
    }

    /**
     * Nastavuje typ ohraniceni objektu
     * @param borderType ohraniceni objektu
     */
    public void setBorderType(BorderType borderType) 
    {
        this.borderType = borderType;
    }

    /**
     * Nastavuje vykreslovany nazev objektu
     * @param objectTitle nazev objektu
     */
    public void setObjectTitle(String objectTitle) 
    {
        this.objectTitle = objectTitle;
    }

    /**
     * Vraci typ ohraniceni objektu
     * @return typ ohraniceni objektu
     */
    public BorderType getBorderType() 
    {
        return borderType;
    }

    /**
     * Vrati nazev objektu
     * 
     * @return nazev objektu
     */
    public String getObjectTitle() 
    {
        return objectTitle;
    }

    /**
     * {@link Drawable#drawObject(Graphics2D)}
     */
    public void drawObject(Graphics2D g2)
    {
        if(!isVisible()) return;

        Stroke savedStroke = g2.getStroke();

        g2.setStroke(BorderType.getBorderStroke(this.borderType));

        Rectangle r  = new Rectangle(getX(), getY(), width, height);

        //vizualizace vyplne (pozadi) objektu
        if (isSelected())
        {
            g2.setColor(Configuration.getColorOfSelected());
            g2.fill( r );
        }
        else
        {
            g2.setColor(Color.WHITE);
            g2.fill( r );
        }

        if(this.isMarked())
        {
        	g2.setColor(Configuration.getColorOfMarked());
        }
        else
        {
        	g2.setColor(Color.BLACK);
        }
        
        // vykresleni hran objektu
        g2.draw( r );
        g2.setColor(Color.BLACK);
        g2.setStroke(savedStroke);
    }

    @Override
    protected void newLineHasBeenAdded(LineEdge attachedEdge)
    {
        attachedEdge.setX(getMidX());
        attachedEdge.setY(getMidY());
    }

    @Override
    public void lineChanged(LineEdge movedEdge)
    {
        // neni potreba delat vubec nic
    }

    @Override
    protected void objectHasMoved(int xDif, int yDif)
    {
        for(LineEdge edge : attachedEdges)
        {
            edge.setX(getMidX());
            edge.setY(getMidY());

            // informuje objekt na druhem konci cary o zmene
            edge.getOppositeEdge().getEdgeOwner().lineChanged(edge);
        }
    }

    /**
     * Nastavi velikost objektu
     * 
     * @param width sirka
     * @param height vyska
     */
    public void setSize(int width, int height)
    {
        this.width = width;
        this.height = height;
    }
}
